package org.bronycorps.mlptss.manager.preferences;

import java.util.HashMap;
import java.util.Map;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Json;

public class GameConfiguration {

	public static class AIConfiguration {
		private float borderMargin;
		private float defaultPositionRadius;
		private float defaultPositionX;
		private float defaultPositionY;
		private float maxPredictedSteps;
		private float predictionStepDuration;
		private float visibilityRadius;
		private float weightBorder;
		private float weightCenter;
		private float weightDodgeEnemy;

		public AIConfiguration() {
			super();
			// TODO Auto-generated constructor stub
		}

		public float getBorderMargin() {
			return this.borderMargin;
		}

		public float getDefaultPositionRadius() {
			return this.defaultPositionRadius;
		}

		public float getDefaultPositionX() {
			return this.defaultPositionX;
		}

		public float getDefaultPositionY() {
			return this.defaultPositionY;
		}

		public float getMaxPredictedSteps() {
			return this.maxPredictedSteps;
		}

		public float getPredictionStepDuration() {
			return this.predictionStepDuration;
		}

		public float getVisibilityRadius() {
			return this.visibilityRadius;
		}

		public float getWeightBorder() {
			return this.weightBorder;
		}

		public float getWeightCenter() {
			return this.weightCenter;
		}

		public float getWeightDodgeEnemy() {
			return this.weightDodgeEnemy;
		}

		public void setBorderMargin(float borderMargin) {
			this.borderMargin = borderMargin;
		}

		public void setDefaultPositionRadius(float defaultPositionRadius) {
			this.defaultPositionRadius = defaultPositionRadius;
		}

		public void setDefaultPositionX(float defaultPositionX) {
			this.defaultPositionX = defaultPositionX;
		}

		public void setDefaultPositionY(float defaultPositionY) {
			this.defaultPositionY = defaultPositionY;
		}

		public void setMaxPredictedSteps(float maxPredictedSteps) {
			this.maxPredictedSteps = maxPredictedSteps;
		}

		public void setPredictionStepDuration(float predictionStepDuration) {
			this.predictionStepDuration = predictionStepDuration;
		}

		public void setVisibilityRadius(float visibilityRadius) {
			this.visibilityRadius = visibilityRadius;
		}

		public void setWeightBorder(float weightBorder) {
			this.weightBorder = weightBorder;
		}

		public void setWeightCenter(float weightCenter) {
			this.weightCenter = weightCenter;
		}

		public void setWeightDodgeEnemy(float weightDodgeEnemy) {
			this.weightDodgeEnemy = weightDodgeEnemy;
		}

	}

	public static class EngineConfiguration {
		private AIConfiguration aiConfig;
		public float bonusSpeed;
		private Integer inputSpeedScale;
		private Map<String, Object> keyMapping = new HashMap<String, Object>();
		private Float missileChainUpgradeFactor;
		private Integer missileLife;
		private String modsPath = "";
		public int nbContinues;
		public Float playerBombCooldown;
		private float playerCooldown;
		private int playerDefaultBombs;
		private int playerLife;
		private int playerMaxBombs;
		private Vector2 playerOriginalPosition;
		private Float playerWeakSpeedRatio;
		public int shieldLife;
		private Float waveCooldown;

		public EngineConfiguration() {
			super();
		}

		public AIConfiguration getAiConfig() {
			return this.aiConfig;
		}

		public float getBonusSpeed() {
			return this.bonusSpeed;
		}

		public Integer getInputSpeedScale() {
			return this.inputSpeedScale;
		}

		public Map<String, Object> getKeyMapping() {
			return this.keyMapping;
		}

		public Float getMissileChainUpgradeFactor() {
			return this.missileChainUpgradeFactor;
		}

		public Integer getMissileLife() {
			return this.missileLife;
		}

		public String getModsPath() {
			return this.modsPath;
		}

		public int getNbContinues() {
			return this.nbContinues;
		}

		public Float getPlayerBombCooldown() {
			return this.playerBombCooldown;
		}

		public float getPlayerCooldown() {
			return this.playerCooldown;
		}

		public int getPlayerDefaultBombs() {
			return this.playerDefaultBombs;
		}

		public int getPlayerLife() {
			return this.playerLife;
		}

		public int getPlayerMaxBombs() {
			return this.playerMaxBombs;
		}

		public Vector2 getPlayerOriginalPosition() {
			return this.playerOriginalPosition;
		}

		public Float getPlayerWeakSpeedRatio() {
			return this.playerWeakSpeedRatio;
		}

		public int getShieldLife() {
			return this.shieldLife;
		}

		public Float getWaveCooldown() {
			return this.waveCooldown;
		}

		public void setAiConfig(AIConfiguration aiConfig) {
			this.aiConfig = aiConfig;
		}

		public void setBonusSpeed(float bonusSpeed) {
			this.bonusSpeed = bonusSpeed;
		}

		public void setInputSpeedScale(Integer inputSpeedScale) {
			this.inputSpeedScale = inputSpeedScale;
		}

		public void setKeyMapping(Map<String, Object> keyMapping) {
			this.keyMapping = keyMapping;
		}

		public void setMissileChainUpgradeFactor(Float missileChainUpgradeFactor) {
			this.missileChainUpgradeFactor = missileChainUpgradeFactor;
		}

		public void setMissileLife(Integer missileLife) {
			this.missileLife = missileLife;
		}

		public void setModsPath(String modsPath) {
			this.modsPath = modsPath;
		}

		public void setNbContinues(int nbContinues) {
			this.nbContinues = nbContinues;
		}

		public void setPlayerBombCooldown(Float playerBombCooldown) {
			this.playerBombCooldown = playerBombCooldown;
		}

		public void setPlayerCooldown(float playerCooldown) {
			this.playerCooldown = playerCooldown;
		}

		public void setPlayerDefaultBombs(int playerDefaultBombs) {
			this.playerDefaultBombs = playerDefaultBombs;
		}

		public void setPlayerLife(int playerLife) {
			this.playerLife = playerLife;
		}

		public void setPlayerMaxBombs(int playerMaxBombs) {
			this.playerMaxBombs = playerMaxBombs;
		}

		public void setPlayerOriginalPosition(Vector2 playerOriginalPosition) {
			this.playerOriginalPosition = playerOriginalPosition;
		}

		public void setPlayerWeakSpeedRatio(Float playerWeakSpeedRatio) {
			this.playerWeakSpeedRatio = playerWeakSpeedRatio;
		}

		public void setShieldLife(int shieldLife) {
			this.shieldLife = shieldLife;
		}

		public void setWaveCooldown(Float waveCooldown) {
			this.waveCooldown = waveCooldown;
		}

	}

	private static GameConfiguration instance = null;

	public static GameConfiguration getInstance() {
		if (instance == null) {
			instance = new GameConfiguration();
		}

		return instance;
	}

	private transient ModConfiguration currentMod;
	private transient String currentModPath = "";

	private transient EngineConfiguration engine;

	private transient boolean ready = false;
	private transient WavesConfiguration wavesConfiguration;

	public GameConfiguration() {
	}

	public String convertPath(String pathname) {
		return this.currentModPath + pathname;
	}

	public AIConfiguration getAiConfig() {
		return this.engine.aiConfig;
	}

	public float getBonusSpeed() {
		return this.engine.bonusSpeed;
	}

	public ModConfiguration getCurrentMod() {
		return this.currentMod;
	}

	public Integer getInputSpeedScale() {
		return this.engine.inputSpeedScale;
	}

	public Integer getKeyMap(String key) {
		float keyMap = (Float) this.engine.keyMapping.get(key);
		return (int) keyMap;
	}

	public Float getMissileChainUpgradeFactor() {
		return this.engine.missileChainUpgradeFactor;
	}

	public Integer getMissileLife() {
		return this.engine.missileLife;
	}

	public String getModsPath() {
		return this.engine.modsPath;
	}

	public int getNbContinues() {
		return this.engine.nbContinues;
	}

	public Float getPlayerBombCooldown() {
		return this.engine.playerBombCooldown;
	}

	public Float getPlayerCooldown() {
		return this.engine.playerCooldown;
	}

	public int getPlayerDefaultBombs() {
		return this.engine.playerDefaultBombs;
	}

	public Integer getPlayerLife() {
		return this.engine.playerLife;
	}

	public int getPlayerMaxBombs() {
		return this.engine.playerMaxBombs;
	}

	public Vector2 getPlayerOriginalPosition() {
		return this.engine.playerOriginalPosition;
	}

	public Float getPlayerWeakSpeedRatio() {
		return this.engine.playerWeakSpeedRatio;
	}

	public int getShieldLife() {
		return this.engine.shieldLife;
	}

	public Float getWaveCooldown() {
		return this.engine.waveCooldown;
	}

	public WavesConfiguration getWavesConfiguration() {
		return this.wavesConfiguration;
	}

	public boolean isReady() {
		return this.ready;
	}

	public void loadFile(String modName) {
		FileHandle configFile = Gdx.files.internal("config.json");
		Json json = new Json();

		EngineConfiguration config = json.fromJson(EngineConfiguration.class,
				configFile);
		this.engine = config;

		FileHandle modConfigFile = Gdx.files.internal(config.getModsPath()
				+ "/" + modName + "/modconfig.json");
		ModConfiguration modConfiguration = json.fromJson(
				ModConfiguration.class, modConfigFile);
		this.currentMod = modConfiguration;

		this.currentModPath = config.getModsPath() + "/" + modName + "/";

		FileHandle trajectConfigFile = Gdx.files
				.internal("default_trajects.json");
		this.wavesConfiguration = json.fromJson(WavesConfiguration.class,
				trajectConfigFile);

		instance.ready = true;
	}

	public void setInputSpeedScale(Integer inputSpeedScale) {
		this.engine.inputSpeedScale = inputSpeedScale;
	}

	public void setMissileLife(Integer missileLife) {
		this.engine.missileLife = missileLife;
	}

	public void setModsPath(String modsPath) {
		this.engine.modsPath = modsPath;
	}

	public void setPlayerCooldown(Float playerCooldown) {
		this.engine.playerCooldown = playerCooldown;
	}

	public void setPlayerDefaultBombs(int playerDefaultBombs) {
		this.engine.playerDefaultBombs = playerDefaultBombs;
	}

	public void setPlayerLife(Integer playerLife) {
		this.engine.playerLife = playerLife;
	}

	public void setPlayerMaxBombs(int playerMaxBombs) {
		this.engine.playerMaxBombs = playerMaxBombs;
	}

	public void setPlayerOriginalPosition(Vector2 playerOriginalPosition) {
		this.engine.playerOriginalPosition = playerOriginalPosition;
	}

	public void setPlayerWeakSpeedRatio(Float playerWeakSpeedRatio) {
		this.engine.playerWeakSpeedRatio = playerWeakSpeedRatio;
	}

	public void setWaveCooldown(Float waveCooldown) {
		this.engine.waveCooldown = waveCooldown;
	}

}
